package leyou.gateway.filter;

import com.leyou.common.auth.JwtUtils;
import com.leyou.common.auth.pojo.Payload;
import com.leyou.common.auth.pojo.UserInfo;
import com.leyou.common.constants.LyConstants;
import leyou.gateway.config.FilterProperties;
import leyou.gateway.config.JwtProperties;
import leyou.gateway.scheduled.AppTokenScheduler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 网关鉴权过滤器
 */
@Component
public class AuthFilter implements GlobalFilter,Ordered{

    @Autowired
    private JwtProperties jwtProps;

    @Autowired
    private FilterProperties filterProps;

//    @Autowired
//    private AppTokenScheduler appTokenScheduler;


    /**
     * 过滤方法
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1）从request取出token
        //1.1 从exchange取出request和response
        //注意：Spring提供ServerHttpRequest对象把原生HttpServletRequest的数据取出，重新封装了一套新的API
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();


//        //往请求头加入服务token
//        String appToken = appTokenScheduler.getAppToken();
//        if(StringUtils.isNotEmpty(appToken)){
//            //1）把新的请求头存入request对象
//            request.mutate().header(LyConstants.APP_TOKEN_HEADER, appToken).build();
//        }


        //判断该请求是否为白名单，如果是，直接放行即可
        //1）获取当前请求路径
        String curURL = request.getURI().getPath(); //  /api/item/category/of/parent
        //2）取出白名单路径
        List<String> allowPaths = filterProps.getAllowPaths();
        //3）判断当前路径是在白名单中
        for(String allowPath:allowPaths){
            if(curURL.contains(allowPath)){
                //直接放行即可
                return chain.filter(exchange);
            }
        }


        //2）使用Jwt工具类校验token的合法性
        Payload<UserInfo> payload= null;
        try {
            //从ServerHttpRequest取出token
            String token = request.getCookies().getFirst(jwtProps.getCookie().getCookieName()).getValue();
            payload = JwtUtils.getInfoFromToken(token, jwtProps.getPublicKey(), UserInfo.class);
        } catch (Exception e) {
            //返回401状态码
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //中止请求
            return response.setComplete();
        }

        //放行该请求
        //chain.filter(exchange): 如果有下一个过滤器则执行下一个过滤器，如果没有，则执行目标资源（微服务）
        return chain.filter(exchange);
    }

    /**
     * 方法返回一个整数，整数代表该过滤器的优先级
     *    数值越大，优先级越小
     * @return
     */
    @Override
    public int getOrder() {
        return 1;
    }
}
